<?php
namespace App\Service\OrderService\OrderRefundService;
use App\Service\BaseService;
use Service\Code\Normal;
use App\Model\PssModel\OrderRefund;
use Service\AppService\IdService;
use App\Model\PssModel\OrderRefundGoods;
use App\Model\PssModel\OrderRefundLog;
use App\Model\PssModel\OrderSupplier;
use App\Service\OrderService\OrderInterfaceService\OrderAfterSaleVerify;
use App\Model\PssModel\OrderRefundSub;
use App\Service\OrderService\OrderBdCrmTradeService;
use Hyperf\DbConnection\Db;
use App\Model\PssModel\Business;
use App\Model\PssModel\OrderSupplierAmountExtra;
use App\Service\OrderService\OrderInterfaceService\OrderPreSellService;
use App\Service\OrderService\OrderInterfaceService\OrderTradeBdCrmCenter;

/**
 * 售后申请记录中心
 */
class OrderRefundMessage extends BaseService
{
    //售后审核付款方式
    const refund_source_cloud   = '1';
    const refund_source_channel = '2';

    //售后申请类型
    const refund_mode_merchant  = '1';
    const refund_mode_user      = '2';
    
    //钱买分
    const refund_extra_mode_type_bd_money_buy_ponits = '1';
    
    //售后方式
    const refund_type_goodsandmoney             = '1';
    const refund_type_refundnotgoodsbutmoney    = '2';
    const refund_type_refundchangegoods         = '3';
    const refund_type_refundsendgoods           = '4';
    const refund_type_refundinsurance           = '5';
    
    //售后状态
    const refund_status_wait_user_rev_goods     = 11; 
    const refund_status_after_sale_success      = 12; 
    
    
    /**`
     * 扩展类型参数
     * 扩展其它交易类型
     * @var array
     */
    public $refund_extra_mode_router = [
        self::refund_extra_mode_type_bd_money_buy_ponits => 'BdMoneyBuyPonits',//钱买分
    ];
    
    
    /**
     * 售后方式方法处理
     * @var 售后状态
     */
    protected $refundTypeMap = 
    [
        self::refund_type_goodsandmoney            => 'refundGoodsAndMoney',//退货退款
        self::refund_type_refundnotgoodsbutmoney   => 'refundNotGoodsButMoney',//不退货仅退款
        self::refund_type_refundchangegoods        => 'refundChangeGoods',//换货申请
        self::refund_type_refundsendgoods          => 'refundSendGoods',//补寄
        self::refund_type_refundinsurance          => 'refundInsurance',//保价
    ];

    /**
     * 售后优惠字段检测
     * @var array
     */
    private $refund_discount_fields = [
        [
            'field'         => 'refund_origin_discount_deposit_delivery_money',
            'origin_field'  => 'discountDepositDeliveryMoney',
            'name'          => '定金运费金额'
        ],
        [
            'field'         => 'refund_origin_discount_deposit_goods_money',
            'origin_field'  => 'discountDepositGoodsMoney',
            'name'          => '定金商品金额'
        ],
        [
            'field'         => 'refund_origin_goods_money',
            'origin_field'  => 'discountGoodsMoney',
            'name'          => '三方实际商品支付金额'
        ],
        [
            'field'         => 'refund_delivery_money',
            'origin_field'  => 'discountDeliveryMoney',
            'name'          => '商品运费金额'
        ],
        [
            'field'         => 'refund_origin_discount_points_money',
            'origin_field'  => 'discountPointsMoney',
            'name'          => '积分金额抵扣'
        ],
        [
            'field'         => 'refund_origin_discount_envelope_money',
            'origin_field'  => 'discountRedEnvelopeMoney',
            'name'          => '红包抵扣'
        ],
        [
            'field'         => 'refund_origin_discount_activity_money',
            'origin_field'  => 'discountActivityMoney',
            'name'          => '活动抵扣'
        ],
        [
            'field'         => 'refund_origin_discount_coupon_money',
            'origin_field'  => 'discountCouponMoney',
            'name'          => '优惠券抵扣'
        ],
        [
            'field'         => 'refund_origin_discount_payway_money',
            'origin_field'  => 'discountPaywayMoney',
            'name'          => '支付方式优惠抵扣'
        ],
        [
            'field'         => 'refund_origin_discount_precard_money',
            'origin_field'  => 'discountPrecardMoney',
            'name'          => '预付卡抵扣'
        ],
        [
            'field'         => 'refund_origin_discount_points',
            'origin_field'  => 'discountPoints',
            'name'          => '积分抵扣'
        ]
    ];
    
    
    /**
     * 验证提交参数
     * @param array $order
     */
    public function voliate(array $order) 
    {
        $rule = [
            "refund_type"           => '售后方式',
            "refund_mode"           => '退款类型',
            "refund_reason_way"     => '申请原因方式',
            "refund_apply_money"    => '申请退款金额',
            "create_user_id"        => '创建人（C端用户mid，云仓后台就是管理员ID）',
            "create_user_name"      => '创建人（如果是用户提的申请就是用户手机号码，如果是后台创建的售后单就是管理员）',
            "exceptReason"          => '售后原因',
            "afterSaleDescription"  => '售后描述',
            "afterSaleAttach"       => '售后相关附件',
            "goodsList"             => "商品组"
        ];
        foreach ($rule as $key => $value ) {
            if( !array_key_exists($key,$order) ) {
                return Normal::returnCode(Normal::FAIL,"请求参数【{$key}】缺失");
            }
        }
        
        if( !is_array($order['goodsList']) ) {
            return Normal::returnCode(Normal::FAIL,"商品组必须要为数组格式的数据");
        }
        
        $goods = current($order['goodsList']);
        $rule = [
            "goodsSku"              => '商品SkuCode',
            "goodsSpecNum"          => '商品goodsSpecNum规格数',
            "goodsRefundNum"        => '售后购买数量',
        ];
        foreach ($rule as $key => $value ) {
            if( !array_key_exists($key,$goods) ) {
                return Normal::returnCode(Normal::FAIL,"请求参数【{$key}】缺失");
            }
        }        
        return Normal::returnCode(Normal::SUC,"校验参数完成");
    }

    /**
     * 添加售后消息申请功能
     * @param array $param['binfo']
     * @param array $param['userOrder']
     * @param array $param['orderSuplier']
     * @param array $param['orderSupplierGoods']
     * @param array $param['supplier']
     */
    public function addRefundLog(array $param)
    {
        $binfo          = $param['binfo'];
        $order          = $param['order'];
        $order_goods    = $order['goodsList'];
        $bid            = $binfo['bid'];
        $supplierOrder  = $param['supplierOrder'];
        $companyInfo    = $param['companyInfo'];
        $orderGoods     = $param['orderGoods'];
        
        //组装原始商品数据map
        $orderGoodsMap  = [];
        foreach ($orderGoods as $item) {
            $orderGoodsMap[$item['skucode']][$item['spec_num']] = $item;
            unset($item);
        }
        
        
        //组装申请接口商品map
        $orderRefundGoodsMap = [];
        foreach ($order_goods as $item) {
            $orderRefundGoodsMap[$item['goodsSku']][$item['goodsSpecNum']] = $item;
            unset($item);
        }
        
        $order_sn           = $supplierOrder['order_sn'];
        $order_id           = (string)$supplierOrder['id'];
        $order_refund_sn    = 'AS'.$order_sn.rand(10000,99999);//售后订单号，默认生成;
        $refund_mode        = $order['refund_mode'];
        $create_user_id     = $order['create_user_id'];
        $create_user_name   = $order['create_user_name'];
        $create_user_name   = $order['create_user_name'];
        $refund_type        = $order['refund_type'];
        
        //云仓后台不能发起针对预售订单的售后功能
        $order_trade_type = $supplierOrder['order_trade_type'];
        if( $refund_mode == self::refund_mode_merchant ) {
            return Normal::returnCode(Normal::FAIL,"平台发起售后单创建操作功能暂未开放，敬请期待!");
        }
        
        if( $refund_mode == self::refund_mode_merchant && OrderSupplier::order_trade_type_deposit == $order_trade_type ) {
            return Normal::returnCode(Normal::FAIL,"平台不能发起针对预售订单的售后操作!");
        }

        //付款审核方式
        if(!in_array($binfo['aftersale_verify_mode'],['1','2']) ) {
            return Normal::returnCode(Normal::FAIL,"付款审核方式数据类型错误，请联系管理员核对渠道配置!");
        }
        
        //当前原始订单需要加入悲观锁，防止出现，重复申请售后数据的问题
        OrderSupplier::instance()->select(['id'])->where('id',$order_id)->lockForUpdate()->first();
        
        $skuCodes = array_keys($orderGoodsMap);
        $refundGoodsList = OrderRefundGoods::instance()->getByGoodsRefundItems($order_id,$skuCodes);
        
        //如果不是保价售后类型，则需要验证售后申请类型是否可以重复
        if( ! $this->isCanRepeatRefundType($refund_type) ) 
        {
            //校验商品申请售后是否超过限制
            if( !empty($refundGoodsList) )
            {
                foreach ($refundGoodsList as $refundGoods)
                {
                    //商品条码
                    $goodsSku       = $refundGoods['skucode'];
                    //商品规格
                    $goodsSpecNum   = $refundGoods['spec_num'];
                    //校验商品异常
                    if( empty($orderRefundGoodsMap[$goodsSku][$goodsSpecNum]) || empty($orderGoodsMap[$goodsSku][$goodsSpecNum]) )
                    {
                        continue;
                    }
            
                    //校验商品是否申请售后超出限制
                    $order_goods_item           = $orderGoodsMap[$goodsSku][$goodsSpecNum];
                    $order_refund_goods_item    = $orderRefundGoodsMap[$goodsSku][$goodsSpecNum];
            
                    //原始商品下单数量
                    $quantity                   = $order_goods_item['quantity'];
            
                    //已申请售后商品数量
                    $total_refund_goods_count   = $refundGoods['total_refund_goods_count'];
            
                    //剩余可以售后商品数量
                    $remain_quantity            = $quantity - $total_refund_goods_count;
            
                    //当期售后申请数量
                    $refund_quantity            = $order_refund_goods_item['goodsRefundNum'];
            
                    //判断申请售后数量是否足够
                    if( $refund_quantity > $remain_quantity )
                    {
                        $goods_name = $order_goods_item['goods_name'];
                        return Normal::returnCode(Normal::FAIL,"原始订单商品行goodsSku【{$goodsSku}】，商品规格数【{$goodsSpecNum}】，商品名称【{$goods_name}】申请售后数量超出限制，剩余可申请售后数量为【{$remain_quantity}】，数量计算规则为下单购买数量，非购买数量x商品规格数量，请联系相关运营人员进行核实处理之后再进行操作!");
                    }
                }
            }
        }
        
        $time = time();
        $info = OrderRefund::instance()->info(['bid'=>$bid,'refund_sn'=>$order_refund_sn]);
        if( !empty($info) ) {
            return Normal::returnCode(Normal::FAIL,"售后订单号order_refund_sn已存在，请重新提交售后操作!");
        }
        
        //组装售后订单
        $order_refund_id = IdService::instance()->getOtherID();
        $orderRefund = [
            'id'                    => $order_refund_id,
            'bid'               	=> $bid,
            'order_sn'          	=> $order_sn,
            'sub_order_sn'      	=> $supplierOrder['supplier_dsn'],
            'sub_order_id'      	=> $supplierOrder['id'],
            'sub_order_status'  	=> $supplierOrder['order_status'],
            'sub_order_money'   	=> $supplierOrder['real_total_money'],
            'supplier_id'       	=> $companyInfo['company_id'],
            'order_express_sn'      => $supplierOrder['express_sn'],
            'refund_sn'         	=> $order_refund_sn,
            'refund_source'         => $binfo['aftersale_verify_mode'],
            'refund_type'       	=> $refund_type,
            'refund_status'     	=> 1,//待审核
            'refund_mode'       	=> $refund_mode,
            'refund_reason_way' 	=> $order['refund_reason_way'],
            'refund_description'    => $order['afterSaleDescription'],
            'refund_attach'         => $order['afterSaleAttach'],
            'refund_apply_money'    => $order['refund_apply_money'],
            'linkphone'             => $order['linkphone'],
            'create_user_id'        => $create_user_id,
            'create_user_name'      => $create_user_name,
            'cd'                    => time()
        ];
        
        //保价不用进行订单售后审核
        if( $refund_type == self::refund_type_refundinsurance ) {
            $orderRefund['refund_order_status'] = 1;
        }
        
        //组装售后商品记录
        $refund_order_goods = [];
        $refund_order_goods_insert = [];
        $total_refund_money                           = '0.00';
        $total_refund_delivery_money                  = '0.00';
        $total_refund_goods_money                     = '0.00';
        $total_refund_discount_money                  = '0.00';
        $total_refund_discount_red_envelope_money     = '0.00';
        $total_refund_discount_activity_money         = '0.00';
        $total_refund_discount_coupon_money           = '0.00';
        $total_refund_discount_payway_money           = '0.00';
        $total_refund_discount_precard_money          = '0.00';
        $total_refund_discount_point_money            = '0.00';
        $total_refund_discount_points                 = '0.00';
        $total_refund_discount_deposit_goods_money    = '0.00';
        $total_refund_discount_deposit_delivery_money = '0.00';
        
        //已申请售后的数据
        $refundGoodsListMap = [];
        foreach ($refundGoodsList as $item) 
        {
            $refundGoodsListMap[$item['skucode']][$item['spec_num']] = $item;
            unset($item);
        }
        
        
        foreach ($order_goods as $goods)
        {
            $goodsSku       = $goods['goodsSku'];
            $goodsSpecNum   = $goods['goodsSpecNum'];
            
            //获取商品skucode
            if( empty($orderGoodsMap[$goodsSku]) ) {
                return Normal::returnCode(Normal::FAIL,"原始订单商品行goodsSku【{$goodsSku}】数据获取失败，请联系系统管理员进行核实之后再进行处理!");
            }
            
            //获取商品skucode 规格
            if( empty($orderGoodsMap[$goodsSku][$goodsSpecNum]) ) {
                return Normal::returnCode(Normal::FAIL,"原始订单商品行goodsSku【{$goodsSku}】下规格数goodsSpecNum【{$goodsSpecNum}】数据获取失败，请联系系统管理员进行核实之后再进行处理!");
            }
            
            $origin_goods_item                      = $orderGoodsMap[$goodsSku][$goodsSpecNum];
            
            //原始商品购买数量
            $quantity                               = $origin_goods_item['quantity'];
            $price                                  = $origin_goods_item['price'];
            $costprice                              = $origin_goods_item['costprice'];
            $settlement_price                       = $origin_goods_item['settlement_price'];
            $delivery_money                         = $origin_goods_item['freight'];
            //优惠分摊明细
            $discount_money                         = $origin_goods_item['discount_money'];
            $discount_red_envelope_money            = $origin_goods_item['discount_red_envelope_money'];
            $discount_activity_money                = $origin_goods_item['discount_activity_money'];
            $discount_coupon_money                  = $origin_goods_item['discount_coupon_money'];
            $discount_payway_money                  = $origin_goods_item['discount_payway_money'];
            $discount_precard_money                 = $origin_goods_item['discount_precard_money'];
            $discount_point_money                   = $origin_goods_item['discount_point_money'];
            $discount_points                        = $origin_goods_item['discount_points'];
            $discount_deposit_goods_money           = $origin_goods_item['discount_deposit_goods_money'];
            $discount_deposit_delivery_money        = $origin_goods_item['discount_deposit_delivery_money'];
            $total_price                            = bcmul((string)$quantity,(string)$price,2);
            $total_real_price                       = bcsub((string)$total_price,(string)$discount_money,2);
            
            //单商品分摊明细
            $single_discount_money                  = bcdiv((string)$discount_money,(string)$quantity,2);
            $single_discount_red_envelope_money     = bcdiv((string)$discount_red_envelope_money,(string)$quantity,2);
            $single_discount_activity_money         = bcdiv((string)$discount_activity_money,(string)$quantity,2);
            $single_discount_coupon_money           = bcdiv((string)$discount_coupon_money,(string)$quantity,2);
            $single_discount_payway_money           = bcdiv((string)$discount_payway_money,(string)$quantity,2);
            $single_discount_precard_money          = bcdiv((string)$discount_precard_money,(string)$quantity,2);
            $single_discount_point_money            = bcdiv((string)$discount_point_money,(string)$quantity,2);
            $single_discount_points                 = bcdiv((string)$discount_points,(string)$quantity,2);
            $single_discount_deposit_goods_money    = bcdiv((string)$discount_deposit_goods_money,(string)$quantity,2);
            $single_discount_deposit_delivery_money = bcdiv((string)$discount_deposit_delivery_money,(string)$quantity,2);
            
            //单商品运费
            $single_delivery_money                  = bcdiv((string)$delivery_money,(string)$quantity,2);
            
            //售后商品数量
            $goodsRefundNum                         = $goods['goodsRefundNum'];
            
            //判断是否是最后一次申请售后
            if( !empty($refundGoodsListMap[$goodsSku]) ) 
            {
                $has_refund                                 = $refundGoodsListMap[$goodsSku][$goodsSpecNum];
                $has_refund_num                             = $has_refund['total_refund_goods_count'];
                $has_refund_discount_money                  = $has_refund['total_refund_discount_money'];
                $has_refund_discount_point_money            = $has_refund['total_refund_discount_point_money'];
                $has_refund_discount_red_envelope_money     = $has_refund['total_refund_discount_red_envelope_money'];
                $has_refund_discount_activity_money         = $has_refund['total_refund_discount_activity_money'];
                $has_refund_discount_coupon_money           = $has_refund['total_refund_discount_coupon_money'];
                $has_refund_discount_payway_money           = $has_refund['total_refund_discount_payway_money'];
                $has_refund_discount_precard_money          = $has_refund['total_refund_discount_precard_money'];
                $has_refund_discount_points                 = $has_refund['total_refund_discount_points'];
                $has_refund_money                           = $has_refund['total_refund_money'];
                $has_refund_goods_money                     = $has_refund['total_refund_goods_money'];
                $has_refund_delivery_money                  = $has_refund['total_refund_delivery_money'];
                $has_refund_discount_deposit_goods_money    = $has_refund['total_refund_discount_deposit_goods_money'];
                $has_refund_discount_deposit_delivery_money = $has_refund['total_refund_discount_deposit_delivery_money'];
            }
            else 
            {
                $has_refund_num                         = 0;
                $has_refund_discount_money              = '0.00';
                $has_refund_discount_point_money        = '0.00';
                $has_refund_discount_red_envelope_money = '0.00';
                $has_refund_discount_activity_money     = '0.00';
                $has_refund_discount_coupon_money       = '0.00';
                $has_refund_discount_payway_money       = '0.00';
                $has_refund_discount_precard_money      = '0.00';
                $has_refund_discount_points             = '0.00';
                $has_refund_discount_deposit_goods_money    = '0.00';
                $has_refund_discount_deposit_delivery_money = '0.00';                
                $has_refund_money                       = '0.00';
                $has_refund_goods_money                 = '0.00';
                $has_refund_delivery_money              = '0.00';
            }
            
            //计算是否是最后一个品进行售后
            if( $has_refund_num + $goodsRefundNum == $quantity )
            {
                //如果是最后一次售后的情况下，需要拿总的减去已售后的数据
                //售后部分优惠明细
                $refund_discount_money                      = bcsub((string)$discount_money,(string)$has_refund_discount_money,2);
                $refund_discount_red_envelope_money         = bcsub((string)$discount_red_envelope_money,(string)$has_refund_discount_red_envelope_money,2);
                $refund_discount_activity_money             = bcsub((string)$discount_activity_money,(string)$has_refund_discount_activity_money,2);
                $refund_discount_coupon_money               = bcsub((string)$discount_coupon_money,(string)$has_refund_discount_coupon_money,2);
                $refund_discount_payway_money               = bcsub((string)$discount_payway_money,(string)$has_refund_discount_payway_money,2);
                $refund_discount_precard_money              = bcsub((string)$discount_precard_money,(string)$has_refund_discount_precard_money,2);
                $refund_discount_point_money                = bcsub((string)$discount_point_money,(string)$has_refund_discount_point_money,2);
                $refund_discount_points                     = bcsub((string)$discount_points,(string)$has_refund_discount_points,2);
                $refund_discount_deposit_goods_money        = bcsub((string)$discount_deposit_goods_money,(string)$has_refund_discount_deposit_goods_money,2);
                $refund_discount_deposit_delivery_money     = bcsub((string)$discount_deposit_delivery_money,(string)$has_refund_discount_deposit_delivery_money,2);
                
                //实际运费
                $refund_delivery_money                      = bcsub((string)$delivery_money,(string)$has_refund_delivery_money,2);
                $total_refund_delivery_money                = bcadd($total_refund_delivery_money,$refund_delivery_money,2);
                //售后实际商品金额
                $refund_goods_money                         = bcsub((string)$total_real_price,(string)$has_refund_goods_money,2);
                //订单维度总优惠明细
                $total_refund_goods_money                   = bcadd($total_refund_goods_money,$refund_goods_money,2);
                //实际商品付款金额 = 商品金额 + 运费
                $refund_money                               = bcadd($refund_goods_money,$refund_delivery_money,2);
                $total_refund_money                         = bcadd($total_refund_money,$refund_money,2);
                
                //优惠明细
                $total_refund_discount_money                = bcadd($total_refund_discount_money,$refund_discount_money);
                $total_refund_discount_red_envelope_money   = bcadd($total_refund_discount_red_envelope_money,$refund_discount_red_envelope_money,2);
                $total_refund_discount_activity_money       = bcadd($total_refund_discount_activity_money,$refund_discount_activity_money,2);
                $total_refund_discount_coupon_money         = bcadd($total_refund_discount_coupon_money,$refund_discount_coupon_money,2);
                $total_refund_discount_payway_money         = bcadd($total_refund_discount_payway_money,$refund_discount_payway_money,2);
                $total_refund_discount_precard_money        = bcadd($total_refund_discount_precard_money,$refund_discount_precard_money,2);
                $total_refund_discount_point_money          = bcadd($total_refund_discount_point_money,$refund_discount_point_money,2);
                $total_refund_discount_points               = bcadd($total_refund_discount_points,$refund_discount_points,2);
                $total_refund_discount_deposit_goods_money  = bcadd($total_refund_discount_deposit_goods_money,$refund_discount_deposit_goods_money,2);
                $total_refund_discount_deposit_delivery_money  = bcadd($total_refund_discount_deposit_delivery_money,$refund_discount_deposit_delivery_money,2);
            }
            else
            {
                //售后商品总价
                $total_refund_price                         = bcmul((string)$price,(string)$goodsRefundNum,2);
                //售后部分优惠明细
                $refund_discount_money                      = bcmul((string)$single_discount_money,(string)$goodsRefundNum,2);
                $refund_discount_red_envelope_money         = bcmul((string)$single_discount_red_envelope_money,(string)$goodsRefundNum,2);
                $refund_discount_activity_money             = bcmul((string)$single_discount_activity_money,(string)$goodsRefundNum,2);
                $refund_discount_coupon_money               = bcmul((string)$single_discount_coupon_money,(string)$goodsRefundNum,2);
                $refund_discount_payway_money               = bcmul((string)$single_discount_payway_money,(string)$goodsRefundNum,2);
                $refund_discount_precard_money              = bcmul((string)$single_discount_precard_money,(string)$goodsRefundNum,2);
                $refund_discount_point_money                = bcmul((string)$single_discount_point_money,(string)$goodsRefundNum,2);
                $refund_discount_points                     = bcmul((string)$single_discount_points,(string)$goodsRefundNum,2);
                $refund_discount_deposit_goods_money        = bcmul((string)$single_discount_deposit_goods_money,(string)$goodsRefundNum,2);
                $refund_discount_deposit_delivery_money     = bcmul((string)$single_discount_deposit_delivery_money,(string)$goodsRefundNum,2);
                
                //售后实际退款金额
                $refund_goods_money                         = bcsub((string)$total_refund_price,(string)$refund_discount_money,2);
                //售后实际运费
                $refund_delivery_money                      = bcmul((string)$single_delivery_money,(string)$goodsRefundNum,2);
                //实际商品付款金额
                $refund_money                               = bcadd($refund_goods_money,$refund_delivery_money,2);
                //订单维度总优惠明细
                $total_refund_money                         = bcadd($total_refund_money,$refund_money,2);
                $total_refund_delivery_money                = bcadd($total_refund_delivery_money,$refund_delivery_money,2);
                $total_refund_goods_money                   = bcadd($total_refund_goods_money,$refund_goods_money,2);
                $total_refund_discount_money                = bcadd($total_refund_discount_money,$refund_discount_money);
                $total_refund_discount_red_envelope_money   = bcadd($total_refund_discount_red_envelope_money,$refund_discount_red_envelope_money,2);
                $total_refund_discount_activity_money       = bcadd($total_refund_discount_activity_money,$refund_discount_activity_money,2);
                $total_refund_discount_coupon_money         = bcadd($total_refund_discount_coupon_money,$refund_discount_coupon_money,2);
                $total_refund_discount_payway_money         = bcadd($total_refund_discount_payway_money,$refund_discount_payway_money,2);
                $total_refund_discount_precard_money        = bcadd($total_refund_discount_precard_money,$refund_discount_precard_money,2);
                $total_refund_discount_point_money          = bcadd($total_refund_discount_point_money,$refund_discount_point_money,2);
                $total_refund_discount_points               = bcadd($total_refund_discount_points,$refund_discount_points,2);
                $total_refund_discount_deposit_goods_money  = bcadd($total_refund_discount_deposit_goods_money,$refund_discount_deposit_goods_money,2);
                $total_refund_discount_deposit_delivery_money  = bcadd($total_refund_discount_deposit_delivery_money,$refund_discount_deposit_delivery_money,2);
            }
            
            $row = [
                'id'                                    => IdService::instance()->getOtherID(),
                'bid'                                   => $bid,
                'refund_order_id'                       => $order_refund_id,
                'order_id'                              => $order_id,
                'goods_type'                            => $origin_goods_item['goods_type'],
                'skucode'                               => $origin_goods_item['skucode'],
                'supplier_skucode'                      => $origin_goods_item['supplier_skucode'],
                'price'                                 => $origin_goods_item['price'],
                'spec_num'                              => $origin_goods_item['spec_num'],
                'buy_num'                               => $quantity,
                'refund_num'                            => $goodsRefundNum,
                
                //售后修改专用
                'refund_origin_money'                          => $refund_money,
                'refund_delivery_money'                        => $refund_delivery_money,
                'refund_origin_goods_money'                    => $refund_goods_money,
                'refund_origin_discount_money'                 => $refund_discount_money,
                'refund_origin_discount_points_money'          => $refund_discount_point_money,
                'refund_origin_discount_envelope_money'        => $refund_discount_red_envelope_money,
                'refund_origin_discount_activity_money'        => $refund_discount_activity_money,
                'refund_origin_discount_coupon_money'          => $refund_discount_coupon_money,
                'refund_origin_discount_payway_money'          => $refund_discount_payway_money,
                'refund_origin_discount_precard_money'         => $refund_discount_precard_money,
                'refund_origin_discount_points'                => $refund_discount_points,
                'refund_origin_discount_deposit_goods_money'    => $refund_discount_deposit_goods_money,
                'refund_origin_discount_deposit_delivery_money' => $refund_discount_deposit_delivery_money,
                
                //crm专用
                'refund_money'                          => $refund_money,
                'refund_goods_money'                    => $refund_goods_money,
                'refund_discount_money'                 => $refund_discount_money,
                'refund_discount_points_money'          => $refund_discount_point_money,
                'refund_discount_envelope_money'        => $refund_discount_red_envelope_money,
                'refund_discount_activity_money'        => $refund_discount_activity_money,
                'refund_discount_coupon_money'          => $refund_discount_coupon_money,
                'refund_discount_payway_money'          => $refund_discount_payway_money,
                'refund_discount_precard_money'         => $refund_discount_precard_money,
                'refund_discount_points'                => $refund_discount_points,                
                'refund_discount_deposit_goods_money'   => $refund_discount_deposit_goods_money,                
                'refund_discount_deposit_delivery_money'=> $refund_discount_deposit_delivery_money,                
                'refund_costprice'                      => $costprice,
                'refund_settlement_price'               => $settlement_price,
                'refund_useable'                        => 1,
                'cd'                                    => $time,
            ];
            $refund_order_goods_insert[] = $row;
            $refund_order_goods[] = $row;
        }
        
        //售后订单汇总
        $orderRefund['refund_origin_money']                     = $total_refund_money;
        $orderRefund['refund_delivery_money']                   = $total_refund_delivery_money;
        $orderRefund['refund_origin_goods_money']               = $total_refund_goods_money;
        $orderRefund['refund_origin_discount_money']            = $total_refund_discount_money;
        $orderRefund['refund_origin_points_money']              = $total_refund_discount_point_money;
        $orderRefund['refund_origin_precard_money']             = $total_refund_discount_precard_money;
        $orderRefund['refund_origin_envelope_money']            = $total_refund_discount_red_envelope_money;
        $orderRefund['refund_origin_coupon_money']              = $total_refund_discount_coupon_money;
        $orderRefund['refund_origin_activity_money']            = $total_refund_discount_activity_money;
        $orderRefund['refund_origin_payway_money']              = $total_refund_discount_payway_money;
        $orderRefund['refund_origin_points_give']               = $total_refund_discount_points;
        $orderRefund['refund_origin_deposit_goods_money']       = $total_refund_discount_deposit_goods_money;
        $orderRefund['refund_origin_deposit_delivery_money']    = $total_refund_discount_deposit_delivery_money;
        
        //crm专用
        $orderRefund['refund_money']                    = $total_refund_money;
        $orderRefund['refund_goods_money']              = $total_refund_goods_money;
        $orderRefund['refund_discount_money']           = $total_refund_discount_money;
        $orderRefund['refund_points_money']             = $total_refund_discount_point_money;
        $orderRefund['refund_precard_money']            = $total_refund_discount_precard_money;
        $orderRefund['refund_envelope_money']           = $total_refund_discount_red_envelope_money;
        $orderRefund['refund_coupon_money']             = $total_refund_discount_coupon_money;
        $orderRefund['refund_activity_money']           = $total_refund_discount_activity_money;
        $orderRefund['refund_payway_money']             = $total_refund_discount_payway_money;
        $orderRefund['refund_points_give']              = $total_refund_discount_points;
        $orderRefund['refund_deposit_goods_money']      = $total_refund_discount_deposit_goods_money;
        $orderRefund['refund_deposit_delivery_money']   = $total_refund_discount_deposit_delivery_money;
        
        //调用百大crm 售后报文
        $is_support_crm_upload = $binfo['is_support_crm_upload'];
        $isDepositMoneyOnly = OrderPreSellService::instance()->isDepositMoneyOnly($order_id);
        if( $is_support_crm_upload == 1 && ! $isDepositMoneyOnly ) 
        {
            //查询扩展订单数据
            $_extra_amount = OrderSupplierAmountExtra::instance()->info(['order_id'=>$order_id]);
            if( empty($_extra_amount['order_crm_create']) ) {
                return Normal::returnCode(Normal::FAIL,"原始上传CRM订单数据异常，请联系管理员核对渠道配置!");
            }
            
            $order_crm_create = json_decode($_extra_amount['order_crm_create'],true);
            $order['refund_extra_value'] = [];
            $order['refund_extra_value']['vipId'] = $order_crm_create['requestData']['vipId'];
            $result = OrderBdCrmTradeService::instance()->uploadBdCrmOrderAfterSale
            (
                $binfo,$orderRefund,$refund_order_goods,$supplierOrder,$order
            );
            if( $result['code'] != Normal::SUC ) {
                return $result;
            }
            
            //返回是否钱买分
            $result_crm = $result['data'];
            if( ! empty($result['data']) )
            {
                //更新CRM订单退款数据
                $orderRefund['refund_bd_crm_contents']      = json_encode($result_crm,JSON_UNESCAPED_UNICODE);
                $orderRefund['refund_crm_amount']           = $result_crm['bd_crm_amount'];
                $orderRefund['refund_crm_delivery_amount']  = $result_crm['bd_crm_delivery_amount'];
                $orderRefund['refund_crm_discount_amount']  = $result_crm['bd_crm_discount_money'];
                $orderRefund['refund_crm_precard_amount']   = $result_crm['bd_crm_precard_money'];
                $orderRefund['refund_crm_points_amount']    = $result_crm['bd_crm_point_money'];
                $orderRefund['refund_crm_qedk_amount']      = $result_crm['bd_crm_qedk_money'];
                $orderRefund['refund_bd_crm_create']        = $result_crm['bd_crm_create'];
            }
        }
        
        //返回结果
        $return = [
            'order_refund_id'   => $order_refund_id,
        ];
        
        
        //处理钱买分业务
        if( $is_support_crm_upload == 1 ) 
        {
            $return['neeBuyCent']        = !empty($result_crm['needBuyCent']) && $result_crm['needBuyCent'] == true ? true : false;
            $return['needBuyCentMoney']  = !empty($result_crm['needBuyCentMoney']) && $result_crm['needBuyCentMoney'] > 0 ? $result_crm['needBuyCentMoney'] : '0.00';
            $return['needBuyCentMsg']    = !empty($result_crm['needBuyCentMsg']) && $result_crm['needBuyCentMsg'] > 0 ? $result_crm['needBuyCentMsg'] : '';
            //如果有钱买分出现的时候，需要记录钱买分申请的售后的数据
            if( $return['neeBuyCent'] == true ) 
            {
                $needBuyCentMoney = $return['needBuyCentMoney'];
                $orderRefund['refund_buy_points_apply_money'] = $needBuyCentMoney;
                
                //如果钱买分不足，需要去购买钱买分
                if( !empty($return['needBuyCentMsg']) ) 
                {
                    $result_points_buy_money = OrderTradeBdCrmCenter::instance()->tradeBuyPoints([
                        'vipId'     => $order_crm_create['requestData']['vipId'],
                        'points'    => bcmul((string)$needBuyCentMoney,'100',2),
                        'money'     => $needBuyCentMoney,
                    ]);
                    if( $result_points_buy_money['code'] != Normal::SUC ) 
                    {
                        return $result;
                    }
                }
            }
        }
        
        OrderRefund::instance()->insert($orderRefund);
        OrderRefundGoods::instance()->insert($refund_order_goods_insert);
        OrderRefundLog::instance()->addLog($order_refund_id, OrderRefund::instance()->refund_mode[$refund_mode], $create_user_id, $create_user_name);
        return Normal::returnCode(Normal::SUC,"售后申请成功",$return);
    }

    /**
     * 是否此单商品是否全部售后
     * 判断当前申请的商品组和已经售后的商品组 是否是此订单全部的商品
     * @param array $param
     */
    public function isAllGoodsRefund(array $param){
        $binfo          = $param['binfo'];
        $order          = $param['order'];
        $order_goods    = $order['goodsList'];//此次申请的商品数据
        $bid            = $binfo['bid'];
        $supplierOrder  = $param['supplierOrder'];
        $companyInfo    = $param['companyInfo'];
        $orderGoods     = $param['orderGoods'];//原始订单商品数据
        $refundGoodsList  = $param['refundGoodsList'];//当前订单是否产生过售后单
        //组装申请接口商品map
        $orderRefundGoodsMap = [];
        foreach ($order_goods as $item) {
            $orderRefundGoodsMap[$item['goodsSku']][$item['goodsSpecNum']] = $item;
            unset($item);
        }
        $order_id           = (string)$supplierOrder['id'];
        // $refundGoodsList = OrderRefundGoods::instance()->getRefundGoodsItemsByOrderId($order_id);
        //已申请售后的商品和当前申请的商品数据
        $refundGoodsListMap = [];
        if( !empty($refundGoodsList) ) {
            foreach ($refundGoodsList as $item) {
                $skucode = $item['skucode'];
                $spec_num = $item['spec_num'];
                //累加已存在的数据
                if( !empty($orderRefundGoodsMap[$skucode]) && !empty($orderRefundGoodsMap[$skucode][$spec_num]) ) {
                    $refundGoodsListMap[$skucode][$spec_num] = [
                        'total_num' => $item['total_refund_goods_count'] + $orderRefundGoodsMap[$skucode][$spec_num]['goodsRefundNum']
                    ];
                    unset($orderRefundGoodsMap[$skucode][$spec_num]);
                } else {
                    $refundGoodsListMap[$skucode][$spec_num] = [
                        'total_num' => $item['total_refund_goods_count']
                    ];
                }
            }
            if( !empty($orderRefundGoodsMap) ) {
                foreach ($orderRefundGoodsMap as $skucode => $specItem ) {
                    foreach ($specItem as $spec_num => $_spec_goods) {
                        $refundGoodsListMap[$skucode][$spec_num] = [
                            'total_num' => $_spec_goods['goodsRefundNum']
                        ];
                    }
                }
            }
        } else {
            foreach ($order_goods as $item) {
                $refundGoodsListMap[$item['goodsSku']][$item['goodsSpecNum']] = [
                    'total_num' => $item['goodsRefundNum']
                ];
                unset($item);
            }
        }
        foreach ($orderGoods as $goodsItem) {
            $skucode = $goodsItem['skucode'];
            $spec_num = $goodsItem['spec_num'];
            if( !isset($refundGoodsListMap[$skucode]) ) {
                return false;
            }
            if( !isset($refundGoodsListMap[$skucode][$spec_num]) ) {
                return false;
            }
            if( $refundGoodsListMap[$skucode][$spec_num]['total_num'] != $goodsItem['quantity'] ) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否全部售后 针对当前售后单判断
     * @param string $order_refund_id
     * @param array $order_supplier_goods
     */
    public function isOrderGoodsAllRefund(string $order_refund_id,array $order_supplier_goods)
    {
        $orderFefundGoods = OrderRefundGoods::instance()
        ->select([
            'skucode',
            'spec_num',
            Db::raw("sum(refund_num) AS refund_num"),
        ])
        ->where('refund_order_id',$order_refund_id)
        ->where('refund_useable',1)
        ->groupBy('skucode')
        ->groupBy('spec_num')
        ->get()
        ->toArray();
        
        $orderFefundGoodsMap = [];
        foreach ($orderFefundGoods as $item)
        {
            $orderFefundGoodsMap[$item['skucode']][$item['spec_num']] = $item;
        }
        
        foreach ($order_supplier_goods as $order_goods)
        {
            $skucode = $order_goods['skucode'];
            $spec_num = $order_goods['spec_num'];
            if( !isset($orderFefundGoodsMap[$skucode]) ) {
                return false;
            }
            
            if( !isset($orderFefundGoodsMap[$skucode][$spec_num]) ) {
                return false;
            }
            
            if( $orderFefundGoodsMap[$skucode][$spec_num]['refund_num'] != $order_goods['quantity'] ) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * 是否属于涉及退款
     * @param int $refundType
     */
    public function isNeedRefundMoney(int $refundType)
    {
        if( in_array($refundType, [OrderRefundMessage::refund_type_refundchangegoods]) ) {
            return false;
        }
        return true;
    }
    
    /**
     * 是否跳过同一个品，同一个数量重复申请售后次数类型
     * @param int $refundType
     */
    public function isCanRepeatRefundType(int $refundType)
    {
        if( in_array($refundType, [OrderRefundMessage::refund_type_refundinsurance]) ) {
            return true;
        }
        return false;
    }
    

    /**
     * 售后订单进行审核
     * @param array $orderRefund
     * @param array $order
     */
    public function orderRefundVerify(array $orderRefund,array $order)
    {
        $order_refund_id    = $orderRefund['id'];
        $refundType         = $order['refundType'];
        $refundTypeWay      = $this->refundTypeMap[$refundType];
        $afterVerifyStatus  = $order['afterVerifyStatus'];
        
        //保价售后订单类型处理
        if( $refundType == self::refund_type_refundinsurance ) {
            return Normal::returnCode(Normal::FAIL,"保价类型售后订单不需要进行二次审核，请联系相关退款单管理人员去核销处理!");
        }
        
        //服务费
        $refundServiceFeeMoney          = !empty($order['refundServiceFeeMoney']) ? $order['refundServiceFeeMoney'] : '0.00';
        //平台承担费用（供货成本价）
        $refundChannelSettlementMoney   = !empty($order['refundChannelSettlementMoney']) ? $order['refundChannelSettlementMoney'] : '0.00';
        //供应商承费用（供货成本价）
        $refundSupplierSettlementMoney  = !empty($order['refundSupplierSettlementMoney']) ? $order['refundSupplierSettlementMoney'] : '0.00';
        //回邮运费
        $replyExpressMoney              = !empty($order['replyExpressMoney']) ? $order['replyExpressMoney'] : '0.00';
        //供应商承担运费
        $supplierExpressMoney           = !empty($order['supplierExpressMoney']) ? $order['supplierExpressMoney'] : '0.00';
        //售后商品应退金额
        $refund_refund_money            = $orderRefund['refund_money'];
        //获取售后商品
        $orderRefundGoods               = OrderRefundGoods::instance()->getRefundGoods($order_refund_id);
        if( empty($orderRefundGoods) ) {
            return Normal::returnCode(Normal::FAIL,"售后商品明细获取失败，请联系相关退款单管理人员去核销处理!");
        }
        
        $refundStatusArr    = [];
        //运营审核拒绝
        if( $afterVerifyStatus == OrderAfterSaleVerify::AFTER_SALE_VERIFY_REJECT) 
        {
            $refundStatusArr = $this->refundStatusArr(3,'拒绝申请，售后关闭');
            $result = OrderRefundGoods::instance()->where('refund_order_id',$order_refund_id)->update([
                'refund_useable'    => 0
            ]);
            if( !$result ) {
                return Normal::returnCode(Normal::FAIL,"售后单审核拒绝，售后商品状态恢复失败，请联系管理进行处理");
            }
            $refund_sub_order_id = 0;
        } 
        else 
        {
            if( empty($order['refundGoods']) ) {
                return Normal::returnCode(Normal::FAIL,"售后单审核refundGoods商品不能为空");
            }
            
            $refundGoods = $order['refundGoods'];
            $currentRefundGoods = current($refundGoods);
            if( empty($currentRefundGoods['dataId']) ) {
                return Normal::returnCode(Normal::FAIL,"售后单审核refundGoods.dataId不能为空");
            }
            
            if( !isset($currentRefundGoods['discountMoney']) ) {
                return Normal::returnCode(Normal::FAIL,"售后单审核refundGoods.discountMoney不能为空");
            }
            
            //校验字段是否OK
            foreach ($this->refund_discount_fields as $item) 
            {
                if( !isset($currentRefundGoods[$item['origin_field']]) ) {
                    return Normal::returnCode(Normal::FAIL,"售后单审核refundGoods.{$item['origin_field']}不能为空");
                }
            }
            
            //获取售后商品
            $orderRefundGoods = OrderRefundGoods::instance()->getRefundGoods($order_refund_id);
            if( empty($orderRefundGoods) ) {
                return Normal::returnCode(Normal::FAIL,"售后商品获取异常");
            }
            $orderRefundGoodsMap = array_column($orderRefundGoods,null,'id');
            
            //售后订单修改之后的最新总金额
            $total_refund_money                           = '0.00';
            $total_refund_goods_money                     = '0.00';
            $total_refund_delivery_money                  = '0.00';
            $total_refund_discount_money                  = '0.00';
            $total_refund_discount_diff_money             = '0.00';
            $total_refund_discount_red_envelope_money     = '0.00';
            $total_refund_discount_activity_money         = '0.00';
            $total_refund_discount_coupon_money           = '0.00';
            $total_refund_discount_payway_money           = '0.00';
            $total_refund_discount_precard_money          = '0.00';
            $total_refund_discount_point_money            = '0.00';
            $total_refund_discount_points                 = '0.00';
            $total_refund_discount_deposit_goods_money    = '0.00';
            $total_refund_discount_deposit_delivery_money = '0.00';
            $total_refund_discount_diff_points            = '0.00';
            foreach ($refundGoods as $refundGoodsItem) 
            {
                $dataId = $refundGoodsItem['dataId'];
                if( empty($orderRefundGoodsMap[$dataId]) ) {
                    return Normal::returnCode(Normal::FAIL,"售后商品数据行ID[{$dataId}]商品获取异常");
                }
                
                $_refund_goods_item         = $orderRefundGoodsMap[$dataId];
                $skucode                    = $_refund_goods_item['skucode'];
                $spec_num                   = $_refund_goods_item['spec_num'];
                foreach ($this->refund_discount_fields as $_fields) 
                {
                    if( bccomp($refundGoodsItem[$_fields['origin_field']],'0.00',2) < 0 )
                    {
                        return Normal::returnCode(Normal::FAIL,"当前修改的{$_fields['name']}[{$refundGoodsItem[$_fields['origin_field']]}]不能小于0");
                    }
                    
                    if( bccomp($refundGoodsItem[$_fields['origin_field']],$_refund_goods_item[$_fields['field']],2) == 1 )
                    {
                        return Normal::returnCode(Normal::FAIL,"当前修改的{$_fields['name']}[{$refundGoodsItem[$_fields['origin_field']]}]不能大于原始{$_fields['name']}[{$_refund_goods_item[$_fields['field']]}]");
                    }
                }
                
                //比对优惠金额明细是否一致
                $_discount_accout_money  = bcadd((string)$refundGoodsItem['discountPointsMoney'],(string)$refundGoodsItem['discountRedEnvelopeMoney'],2);
                $_discount_accout_money  = bcadd((string)$_discount_accout_money,(string)$refundGoodsItem['discountActivityMoney'],2);
                $_discount_accout_money  = bcadd((string)$_discount_accout_money,(string)$refundGoodsItem['discountPaywayMoney'],2);
                $_discount_accout_money  = bcadd((string)$_discount_accout_money,(string)$refundGoodsItem['discountCouponMoney'],2);
                $_discount_accout_money  = bcadd((string)$_discount_accout_money,(string)$refundGoodsItem['discountPrecardMoney'],2);
                $_discount_accout_money  = bcadd((string)$_discount_accout_money,(string)$refundGoodsItem['discountDepositGoodsMoney'],2);
                $_discount_accout_money  = bcadd((string)$_discount_accout_money,(string)$refundGoodsItem['discountDepositDeliveryMoney'],2);
                
                if( bccomp((string)$_discount_accout_money,(string)$refundGoodsItem['discountMoney'],2) != 0) 
                {
                    return Normal::returnCode(Normal::FAIL,"商品行优惠金额明细汇总[{$_discount_accout_money}]不等于商品行优惠金额汇总[{$refundGoodsItem['discountMoney']}]，请核对！");
                }
                
                //原始数据的优惠总金额
                $refund_origin_discount_money   = $_refund_goods_item['refund_origin_discount_money'];
                $_diff_discount_money           = bcsub($refund_origin_discount_money,$_discount_accout_money,2);
                
                //差异积分
                $refund_origin_discount_points  = $_refund_goods_item['refund_origin_discount_points'];
                $_diff_discount_points          = bcsub($refund_origin_discount_points,$refundGoodsItem['discountPoints'],2);
                
                //商品支付金额
                $refund_goods_money     = $refundGoodsItem['discountGoodsMoney'];
                //运费
                $refund_delivery_money  = $refundGoodsItem['discountDeliveryMoney'];
                //总金额   = 商品支付金额 + 运费
                $refund_money           = bcadd($refund_goods_money,$refund_delivery_money,2);
                
                //修改之后的商品金额
                $total_refund_discount_money                    = bcadd($total_refund_discount_money,$_discount_accout_money,2);
                $total_refund_discount_diff_money               = bcadd($total_refund_discount_diff_money,$_diff_discount_money,2);
                $total_refund_discount_point_money              = bcadd($total_refund_discount_point_money,(string)$refundGoodsItem['discountPointsMoney'],2);
                $total_refund_discount_red_envelope_money       = bcadd($total_refund_discount_red_envelope_money,(string)$refundGoodsItem['discountRedEnvelopeMoney'],2);
                $total_refund_discount_activity_money           = bcadd($total_refund_discount_activity_money,(string)$refundGoodsItem['discountActivityMoney'],2);
                $total_refund_discount_coupon_money             = bcadd($total_refund_discount_coupon_money,(string)$refundGoodsItem['discountCouponMoney'],2);
                $total_refund_discount_payway_money             = bcadd($total_refund_discount_payway_money,(string)$refundGoodsItem['discountPaywayMoney'],2);
                $total_refund_discount_precard_money            = bcadd($total_refund_discount_precard_money,(string)$refundGoodsItem['discountPrecardMoney'],2);
                $total_refund_discount_points                   = bcadd($total_refund_discount_points,(string)$refundGoodsItem['discountPoints'],2);
                $total_refund_discount_deposit_goods_money      = bcadd($total_refund_discount_deposit_goods_money,(string)$refundGoodsItem['discountDepositGoodsMoney'],2);
                $total_refund_discount_deposit_delivery_money   = bcadd($total_refund_discount_deposit_delivery_money,(string)$refundGoodsItem['discountDepositDeliveryMoney'],2);
                $total_refund_discount_diff_points              = bcadd($total_refund_discount_diff_points,$_diff_discount_points,2);
                $total_refund_delivery_money                    = bcadd($total_refund_delivery_money,$refund_delivery_money,2);
                $total_refund_goods_money                       = bcadd($total_refund_goods_money,$refund_goods_money,2);
                $total_refund_money                             = bcadd($total_refund_money,$refund_money,2);
                
                //开始修改每个商品的优惠明细数据
                $_update_data = [
                    'refund_money'                              => $refund_money,
                    'refund_delivery_money'                     => $refund_delivery_money,
                    'refund_goods_money'                        => $refund_goods_money,
                    'refund_discount_money'                     => $_discount_accout_money,
                    'refund_discount_diff_money'                => $_diff_discount_money,
                    'refund_discount_points_money'              => $refundGoodsItem['discountPointsMoney'],
                    'refund_discount_envelope_money'            => $refundGoodsItem['discountRedEnvelopeMoney'],
                    'refund_discount_activity_money'            => $refundGoodsItem['discountActivityMoney'],
                    'refund_discount_coupon_money'              => $refundGoodsItem['discountCouponMoney'],
                    'refund_discount_payway_money'              => $refundGoodsItem['discountPaywayMoney'],
                    'refund_discount_precard_money'             => $refundGoodsItem['discountPrecardMoney'],
                    'refund_discount_points'                    => $refundGoodsItem['discountPoints'],
                    'refund_discount_deposit_goods_money'       => $refundGoodsItem['discountDepositGoodsMoney'],
                    'refund_discount_deposit_delivery_money'    => $refundGoodsItem['discountDepositDeliveryMoney'],
                    'refund_discount_diff_points'               => $_diff_discount_points
                ];
                
                OrderRefundGoods::instance()->where('id',$dataId)->update($_update_data);
            }
            
            $refundStatusArr = $this->{$refundTypeWay}($order);
            
            if( !empty($order['refund_modity']) && $order['refund_modity'] == 1 ) {
                $refundStatusArr['refund_status'] = 1;
            } else {
                $refundStatusArr['refund_amount_status'] = 0;
            }
            
            $binfo              = Business::instance()->getUserInfoByBid($orderRefund['bid']);
            $order_supplier_id  = $orderRefund['sub_order_id'];
            $supplierOrder      = OrderSupplier::instance()->info(['id'=>$order_supplier_id]);
            
            //判断是否只付了定金
            $isDepositMoneyOnly = OrderPreSellService::instance()->isDepositMoneyOnly($order_supplier_id);
            
            //处理钱买分金额
            $refund_buy_points_money = '0.00';
            $needBuyCent = false;
            $needBuyCentMsg = '';
            $is_support_crm_upload = $binfo['is_support_crm_upload'];
            if( !$isDepositMoneyOnly && $is_support_crm_upload == 1 )
            {
                if( empty($orderRefund['refund_bd_crm_create']) ) {
                    return Normal::returnCode(Normal::FAIL,"售后申请crm交易报文查询失败，请联系相关退款单管理人员去核销处理!");
                }
                $refund_bd_crm_create = @json_decode($orderRefund['refund_bd_crm_create'],true);
                if( empty($refund_bd_crm_create) ) {
                    return Normal::returnCode(Normal::FAIL,"售后crm交易查询解析失败，请联系相关退款单管理人员去核销处理!");
                }
            
                //组装会员ID
                $order['refund_extra_value']['vipId'] = $refund_bd_crm_create['requestData']['vipId'];
            
                //获取钱买分抵扣金额
                $result_crm = OrderBdCrmTradeService::instance()->uploadBdCrmOrderAfterSale(
                    $binfo,
                    $orderRefund,
                    $orderRefundGoods,
                    $supplierOrder,
                    $order
                    );
                if( $result_crm['code'] != Normal::SUC ) {
                    return Normal::returnCode(Normal::FAIL,"查询CRM售后交易失败[{$result_crm['msg']}]");
                }
                //钱买分金额
                $refund_buy_points_money = (string)$result_crm['data']['needBuyCentMoney'];
                $needBuyCent = $result_crm['data']['needBuyCent'];
                $needBuyCentMsg = $result_crm['data']['needBuyCentMsg'];
                
                //扣款顺序-积分->预付卡-在线三方支付->红包->优惠券->活动(钱买分)
                if( $needBuyCent && !empty($needBuyCentMsg) && empty($refund_bd_crm_create['isNeedBuyCent']) )
                {
                    //调用钱买分接口
                    $result_buy_points = OrderTradeBdCrmCenter::instance()->tradeBuyPoints([
                        'requestData'   => [
                            'vipId'     => $refund_bd_crm_create['requestData']['vipId'],
                            'points'    => $result_crm['data']['thjf'] > 0 ? $result_crm['data']['thjf'] : 0 - $result_crm['data']['thjf'],
                            'money'     => $refund_buy_points_money
                        ]
                    ]);
                    if( $result_buy_points['code'] != Normal::SUC ) {
                        return Normal::returnCode(Normal::FAIL,"前钱买分接口处理请求失败【{$result_buy_points['msg']}】");
                    }
                    $refund_bd_crm_create['isNeedBuyCent'] = '1';
                    $refundStatusArr['refund_bd_crm_create'] = json_encode($refund_bd_crm_create,JSON_UNESCAPED_UNICODE);
                }
            }
            
            //计算售后服务费用
            //实际退款金额（售后商品应退金额-服务手续费金额-钱买分金额）
            $refund_realy_money    = bcsub((string)$refund_refund_money, (string)$refundServiceFeeMoney,2);
            if( $refund_realy_money < 0 && $this->isNeedRefundMoney((int)$refundType)) {
                return Normal::returnCode(Normal::FAIL,"实际退款金额不能小于等于 0，数据【申请退款金额为:{$refund_refund_money},服务费为:{$refundServiceFeeMoney},钱买分:{$refund_buy_points_money}】");
            }
            
            //钱买分字段比较
            $_compare_money_arr = [
                'total_refund_discount_point_money'             => ['money'=>$total_refund_discount_point_money,'way'=>'points'],
                'total_refund_discount_precard_money'           => ['money'=>$total_refund_discount_precard_money,'way'=>'precard'],
                'total_refund_money'                            => ['money'=>$total_refund_money,'way'=>'thirdparty'],
                'total_refund_discount_coupon_money'            => ['money'=>$total_refund_discount_coupon_money,'way'=>'coupon'],
                'total_refund_discount_red_envelope_money'      => ['money'=>$total_refund_discount_red_envelope_money,'way'=>'envelope'],
                'total_refund_discount_payway_money'            => ['money'=>$total_refund_discount_payway_money,'way'=>'payway'],
                'total_refund_discount_activity_money'          => ['money'=>$total_refund_discount_activity_money,'way'=>'activity'],
            ];
            
            //扣款顺序-积分->预付卡-在线三方支付->红包->优惠券->活动(钱买分)
            if( $needBuyCent && !empty($needBuyCentMsg) ) 
            {
                //积分抵扣足够
                $refund_buy_points = bcmul($refund_buy_points_money,'100',2);
                $refund_buy_way    = '';
                foreach ($_compare_money_arr as $_key_index => & $item) 
                {
                    if( bccomp((string)$item['money'],$refund_buy_points_money,2) >= 0 ) 
                    {
                        $refund_buy_way = $item['way'];
                        $item['money'] = bcsub((string)$item['money'],$refund_buy_points_money,2);
                        break;
                    }
                }
                $refundStatusArr['refund_buy_points_way'] = $refund_buy_way;
                $total_refund_discount_point_money          = $_compare_money_arr['total_refund_discount_point_money']['money'];
                $total_refund_discount_precard_money        = $_compare_money_arr['total_refund_discount_precard_money']['money'];
                $total_refund_money                         = $_compare_money_arr['total_refund_money']['money'];
                $total_refund_discount_coupon_money         = $_compare_money_arr['total_refund_discount_coupon_money']['money'];
                $total_refund_discount_red_envelope_money   = $_compare_money_arr['total_refund_discount_red_envelope_money']['money'];
                $total_refund_discount_payway_money         = $_compare_money_arr['total_refund_discount_payway_money']['money'];
                $total_refund_discount_activity_money       = $_compare_money_arr['total_refund_discount_activity_money']['money'];
            }
            
            //计算实际退款总额度
            $refundStatusArr['refund_type']                         = $refundType;
            $refundStatusArr['refund_realy_money']                  = $refund_realy_money;
            $refundStatusArr['refund_buy_points_money']             = $refund_buy_points_money;
            $refundStatusArr['refund_service_fee_money']            = $refundServiceFeeMoney;
            $refundStatusArr['refund_channel_settlement_money']     = $refundChannelSettlementMoney;
            $refundStatusArr['refund_supplier_settlement_money']    = $refundSupplierSettlementMoney;
            $refundStatusArr['reply_express_money']                 = $replyExpressMoney;
            $refundStatusArr['supplier_express_money']              = $supplierExpressMoney;
            
            //优惠差异部分
            $refundStatusArr['refund_money']                        = $total_refund_money;
            $refundStatusArr['refund_delivery_money']               = $total_refund_delivery_money;
            $refundStatusArr['refund_goods_money']                  = $total_refund_goods_money;
            $refundStatusArr['refund_discount_diff_money']          = $total_refund_discount_diff_money;
            $refundStatusArr['refund_points_money']                 = $total_refund_discount_point_money;
            $refundStatusArr['refund_activity_money']               = $total_refund_discount_activity_money;
            $refundStatusArr['refund_coupon_money']                 = $total_refund_discount_coupon_money;
            $refundStatusArr['refund_payway_money']                 = $total_refund_discount_payway_money;
            $refundStatusArr['refund_precard_money']                = $total_refund_discount_precard_money;
            $refundStatusArr['refund_envelope_money']               = $total_refund_discount_red_envelope_money;
            $refundStatusArr['refund_points_give']                  = $total_refund_discount_points;
            $refundStatusArr['refund_deposit_goods_money']          = $total_refund_discount_deposit_goods_money;
            $refundStatusArr['refund_deposit_delivery_money']       = $total_refund_discount_deposit_delivery_money;
            $refundStatusArr['refund_points_diff_give']             = $total_refund_discount_diff_points;

            //审核人信息
            $refundStatusArr['verify_user_id']                      = !empty($order['sysUserID'])   ? $order['sysUserID']   : 0 ;
            $refundStatusArr['verify_user_name']                    = !empty($order['sysUserName']) ? $order['sysUserName'] : '' ;
            $refundStatusArr['verify_time']                         = time();
            
            //换货不生成退款单号
            if($this->isNeedRefundMoney((int)$refundType) && $binfo['is_full_support_after_sale'] == 1 && $orderRefund['refund_source'] == 1){
                $refundStatusArr['refund_order_status']                 = 1;//退款单生成
                $refundStatusArr['refund_order_sn']                     = 'TK'.$order_refund_id;//退款订单号
                $refundStatusArr['refund_order_time']                   = date("Y-m-d H:i:s");
            }
            
            //组装售后子订单明细
            $order_refund_sn = $orderRefund['refund_sn'];
            $refund_sub_order_id = IdService::instance()->getOtherID();
            $refund_order_sub = [
                'id'                                        => $refund_sub_order_id,
                'bid'               						=> $orderRefund['bid'],
                'refund_sn'         						=> $order_refund_sn,
                'refund_sub_sn'     						=> 'AS-SUB-'.$refund_sub_order_id,
                'refund_order_id'   						=> $order_refund_id,
                'refund_sub_type'   						=> 1,
                'refund_supplier_current_settlement_money'  => $refundServiceFeeMoney,
                'refund_channel_current_settlement_money'   => $refundChannelSettlementMoney,
                'refund_supplier_current_delivery_money'    => $supplierExpressMoney,
                'refund_settlement_status'                  => 0,
                'system_user_id'    						=> $order['sysUserID'],
                'system_user_name'  						=> $order['sysUserName'],
                'cd'                						=> time(),
            ];
            OrderRefundSub::instance()->insert($refund_order_sub);
        }
        
        //获取对应售后方式通道数据
        $refundStatusArr['md'] = time();
        $result = OrderRefund::instance()
        ->where('id',$order_refund_id)->where('refund_status','>',0)->where('refund_amount_status','!=',1)
        ->update($refundStatusArr);
        if( $result ) {
            return Normal::returnCode(Normal::SUC,"操作成功",[
                'refund_sub_order_id'   => $refund_sub_order_id,
            ]);
        }
        return Normal::returnCode(Normal::FAIL,"操作失败，请刷新页面重试!");
    }
    
    /**
     * 退货退款
     * @param array $order
     */
    public function refundGoodsAndMoney(array $order)
    {
        return $this->refundStatusArr(5,'已同意退货退款,待用户发货');
    }
    
    /**
     * 不退货退款
     * @param array $order
     */
    public function refundNotGoodsButMoney(array $order)
    {
        return $this->refundStatusArr(2,'同意退款，退款中');
    }
    
    /**
     * 换货
     * @param array $order
     */
    public function refundChangeGoods(array $order)
    {
        return $this->refundStatusArr(7,'已同意换货申请，待用户发货');
    }
    
    /**
     * 补寄
     * @param array $order
     */
    public function refundSendGoods(array $order)
    {
        return $this->refundStatusArr(14,'已同意补寄货物');
    }
    
    /**
     * 组装售后类型报文
     * @param int $refund_status
     * @param string $refund_name
     */
    private function refundStatusArr(int $refund_status,string $refund_name) 
    {
        return [
            'refund_status' => $refund_status,
            'refund_remark' => $refund_name
        ];
    }
}
